﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Quexcel.OpenXML.Interfaces;
using System.Xml;
using System.IO.Packaging;
using Quexcel.OpenXML.Exceptions;
using System.IO;
using Quexcel.OpenXML.Utils;

namespace Quexcel.OpenXML.Excel.Workbook.IO
{
    internal class WorkbookWriter : WorkbookReader, IWorkbookWriter
    {
        internal WorkbookWriter(PackagePart workbookPart, Package xlPackage)
            : base(workbookPart, xlPackage)
        {
            
        }

        #region IWriter Members

        public bool Write(string addressName, string value)
        {
            throw new NotImplementedException();
        }

        public void ModifyRange(string rangeName, string newRangeAddress)
        {
            string searchString = string.Format("//d:definedName[@name='{0}']", rangeName);
            XmlNode rangeNode = workbookDoc.SelectSingleNode(searchString, NameSpaceManager);

            if (rangeNode != null)
                rangeNode.InnerText = newRangeAddress;
            else
                throw new InvalidTableStructureException(rangeName, "Cannot modify the table. No such table exists.");
        }

        public void AddRange(string rangeName, string rangeAddress)
        {
            string searchString = string.Format("//d:definedName[@name='{0}']", rangeName);
            XmlNode rangeNode = workbookDoc.SelectSingleNode(searchString, NameSpaceManager);

            if (rangeNode != null)
                throw new InvalidTableStructureException(rangeName, "Cannot create table with the name as table with the same name already exists.");
            else
            {
                XmlElement cellElement = workbookDoc.CreateElement("definedName", DocumentInfo.WorksheetSchema);
                cellElement.Attributes.Append(workbookDoc.CreateAttribute("name"));
                cellElement.Attributes["name"].Value = rangeName;
                cellElement.InnerText = rangeAddress;

                XmlNode definedNamesNode = workbookDoc.SelectSingleNode("//d:definedNames", NameSpaceManager);
                definedNamesNode.AppendChild(cellElement);
            }
        }

        public bool Flush()
        {
            try
            {
                workbookDoc.Save(documentPart.GetStream(FileMode.Create, FileAccess.Write));
                return true;
            }
            catch
            {
                return false;
            }
            finally
            {
                this.Close();
            }
        }

        public void Close()
        {
            
        }

        #endregion

        #region IWorkbookWriter Members

        public bool Reset()
        {
            try
            {
                workbookDoc.Load(documentPart.GetStream());
                return true;
            }
            catch
            {
                return false;
            }
        }

        #endregion
    }
}
